/**
 * elancom Corporation copy right 2012 - 2015  
 *   
 * $Header: https://192.168.1.224/svn/elancom/product/elancom-platform/trunk/src/main/java/com/elancom/framework/commons/json/parser/deserializer/SqlDateDeserializer.java 1034 2012-07-02 03:09:12Z lanzhouxue $
 * $Id: SqlDateDeserializer.java 1034 2012-07-02 03:09:12Z lanzhouxue $
 * $Author: lanzhouxue $
 * $Date: 2012-07-02 11:09:12 +0800 (Mon, 02 Jul 2012) $
 * $Revision: 1034 $
 */
package com.elancom.framework.commons.json.parser.deserializer;

import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;

import com.elancom.framework.commons.json.JSONException;
import com.elancom.framework.commons.json.parser.DefaultJSONParser;
import com.elancom.framework.commons.json.parser.JSONScanner;
import com.elancom.framework.commons.json.parser.JSONToken;

public class SqlDateDeserializer extends AbstractDateDeserializer implements ObjectDeserializer {

	public final static SqlDateDeserializer instance = new SqlDateDeserializer();

	@Override
	@SuppressWarnings("unchecked")
	protected <T> T cast(DefaultJSONParser parser, Type clazz, Object fieldName, Object val) {
		if (val == null) {
			return null;
		}

		if (val instanceof java.util.Date) {
			val = new java.sql.Date(((Date) val).getTime());
		} else if (val instanceof Number) {
			val = new java.sql.Date(((Number) val).longValue());
		} else if (val instanceof String) {
			final String strVal = (String) val;
			if (strVal.length() == 0) {
				return null;
			}

			long longVal;

			final JSONScanner dateLexer = new JSONScanner(strVal);
			if (dateLexer.scanISO8601DateIfMatch()) {
				longVal = dateLexer.getCalendar().getTimeInMillis();
			} else {

				final DateFormat dateFormat = parser.getDateFormat();
				try {
					final java.util.Date date = dateFormat.parse(strVal);
					return (T) new java.sql.Date(date.getTime());
				} catch (final ParseException e) {
					// skip
				}

				longVal = Long.parseLong(strVal);
			}
			return (T) new java.sql.Date(longVal);
		} else {
			throw new JSONException("parse error : " + val);
		}

		return (T) val;
	}

	@Override
	public int getFastMatchToken() {
		return JSONToken.LITERAL_INT;
	}
}
